#ifndef BLOCKQUEUE_H
#define BLOCKQUEUE_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdbool.h>

#define GMAXCAP 500 // 默认的最大队列容量

// 定义阻塞队列的结构体
typedef struct BlockQueue
{
    void **queue;          // 使用void**来存储任意类型的指针
    int max_cap;           // 队列的最大容量
    int head;              // 队列头部索引
    int tail;              // 队列尾部索引
    int count;             // 当前队列中的元素数量
    pthread_mutex_t mutex; // 互斥锁，用于保护队列的访问
    pthread_cond_t pcond;  // 生产者条件变量
    pthread_cond_t ccond;  // 消费者条件变量
} BlockQueue;

// 创建阻塞队列
BlockQueue *block_queue_create(int max_cap)
{
    BlockQueue *queue = (BlockQueue *)malloc(sizeof(BlockQueue)); // 分配BlockQueue结构体的内存
    if (!queue)
        return NULL; // 如果内存分配失败，返回NULL

    queue->queue = (void **)malloc(max_cap * sizeof(void *)); // 分配队列数组的内存
    if (!queue->queue)
    {
        free(queue); // 如果队列数组内存分配失败，释放BlockQueue结构体的内存
        return NULL;
    }

    queue->max_cap = max_cap; // 设置队列的最大容量
    queue->head = 0;          // 初始化队列头部索引
    queue->tail = 0;          // 初始化队列尾部索引
    queue->count = 0;         // 初始化队列中的元素数量

    pthread_mutex_init(&queue->mutex, NULL); // 初始化互斥锁
    pthread_cond_init(&queue->pcond, NULL);  // 初始化生产者条件变量
    pthread_cond_init(&queue->ccond, NULL);  // 初始化消费者条件变量

    return queue; // 返回创建的队列
}

// 销毁阻塞队列
void block_queue_destroy(BlockQueue *queue)
{
    if (queue)
    {
        free(queue->queue);                   // 释放队列数组的内存
        pthread_mutex_destroy(&queue->mutex); // 销毁互斥锁
        pthread_cond_destroy(&queue->pcond);  // 销毁生产者条件变量
        pthread_cond_destroy(&queue->ccond);  // 销毁消费者条件变量
        free(queue);                          // 释放BlockQueue结构体的内存
    }
}

// 判断队列是否为空
bool block_queue_is_empty(BlockQueue *queue)
{
    return queue->count == 0; // 如果队列中的元素数量为0，则队列为空
}

// 判断队列是否已满
bool block_queue_is_full(BlockQueue *queue)
{
    return queue->count == queue->max_cap; // 如果队列中的元素数量等于最大容量，则队列已满
}

// 向队列添加元素
void block_queue_push(BlockQueue *queue, void *item)
{
    pthread_mutex_lock(&queue->mutex); // 加锁，确保线程安全

    while (block_queue_is_full(queue))
    {                                                    // 如果队列已满
        pthread_cond_wait(&queue->pcond, &queue->mutex); // 生产者等待，直到队列有空位
    }

    queue->queue[queue->tail] = item;                 // 将元素添加到队列尾部
    queue->tail = (queue->tail + 1) % queue->max_cap; // 更新队列尾部索引，实现循环队列
    queue->count++;                                   // 增加队列中的元素数量

    pthread_cond_signal(&queue->ccond);  // 通知一个等待的消费者，队列中有新元素
    pthread_mutex_unlock(&queue->mutex); // 解锁
}

// 从队列移除元素
void block_queue_pop(BlockQueue *queue, void **item)
{
    pthread_mutex_lock(&queue->mutex); // 加锁，确保线程安全

    while (block_queue_is_empty(queue))
    {                                                    // 如果队列为空
        pthread_cond_wait(&queue->ccond, &queue->mutex); // 消费者等待，直到队列中有元素
    }

    *item = queue->queue[queue->head];                // 从队列头部取出元素
    queue->head = (queue->head + 1) % queue->max_cap; // 更新队列头部索引，实现循环队列
    queue->count--;                                   // 减少队列中的元素数量

    pthread_cond_signal(&queue->pcond);  // 通知一个等待的生产者，队列中有空位
    pthread_mutex_unlock(&queue->mutex); // 解锁
}

#endif // BLOCKQUEUE_H